package top.frsf.manage.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import top.frsf.common.utils.StringUtils;
import top.frsf.manage.domain.dto.AccessTokenResponse;
import top.frsf.manage.domain.dto.PhoneNumberResponse;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

// WeChatService.java
@Service
@Slf4j
public class WeChatService implements IWeChatService {

    @Value("${wechat.appid}")
    private String appid;

    @Value("${wechat.secret}")
    private String secret;

    @Value("${wechat.access-token-url}")
    private String accessTokenUrl;

    @Value("${wechat.phone-number-url}")
    private String phoneNumberUrl;

    @Autowired
    public  RedisTemplate redisTemplate;

    private static final String ACCESS_TOKEN_KEY = "wechat:access_token";
    private static final long ACCESS_TOKEN_EXPIRE = 7000; // 微信access_token有效期为7200秒，这里设置为7000秒

    /**
     * 获取微信access_token（带缓存）
     */
    public String getAccessToken() {
        // 先从Redis获取
        String accessToken = (String) redisTemplate.opsForValue().get(ACCESS_TOKEN_KEY);
        if (StringUtils.hasText(accessToken)) {
            return accessToken;
        }

        // 调用微信接口获取access_token
        String url = String.format("%s?grant_type=client_credential&appid=%s&secret=%s",
                                  accessTokenUrl, appid, secret);

        try {
            RestTemplate restTemplate = new RestTemplate();
            AccessTokenResponse response = restTemplate.getForObject(url, AccessTokenResponse.class);

            if (response != null && response.getAccess_token() != null) {
                accessToken = response.getAccess_token();
                // 存入Redis，设置过期时间
                redisTemplate.opsForValue().set(ACCESS_TOKEN_KEY, accessToken,
                                               ACCESS_TOKEN_EXPIRE, TimeUnit.SECONDS);
                return accessToken;
            } else {
                log.error("获取access_token失败: {}", response != null ? response.getErrmsg() : "未知错误");
                throw new RuntimeException("获取access_token失败");
            }
        } catch (Exception e) {
            log.error("获取access_token异常", e);
            throw new RuntimeException("获取access_token异常", e);
        }
    }

    /**
     * 获取用户手机号
     */
    public PhoneNumberResponse getPhoneNumber(String code) {
        String accessToken = getAccessToken();
        String url = String.format("%s?access_token=%s", phoneNumberUrl, accessToken);

        try {
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            Map<String, String> requestBody = new HashMap<>();
            requestBody.put("code", code);

            HttpEntity<Map<String, String>> request = new HttpEntity<>(requestBody, headers);
            ResponseEntity<PhoneNumberResponse> response = restTemplate.postForEntity(
                url, request, PhoneNumberResponse.class);

            PhoneNumberResponse phoneNumberResponse = response.getBody();
            if (phoneNumberResponse != null && phoneNumberResponse.getErrcode() == 0) {
                return phoneNumberResponse;
            } else {
                log.error("获取手机号失败: {}", phoneNumberResponse != null ?
                         phoneNumberResponse.getErrmsg() : "未知错误");
                throw new RuntimeException("获取手机号失败");
            }
        } catch (Exception e) {
            log.error("获取手机号异常", e);
            throw new RuntimeException("获取手机号异常", e);
        }
    }
}
